home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************
-
- IPCWindow.c
-
- Does open a simple window with some easy gadgets, does create a
- new process, is protected to launch not twice and does show all
- arguments even if they are given with a new command.
-
- *********************************************************************/
-
- #define PARENT
- #include "/includes/Window.h"
-
- typedef struct _PassingData
- {
- ULONG a4; // to store a4 (module is a4 relative)
- struct Library *library; // to store a pointer to dopus5.library
- struct Library *module; // to store a pointer to this module
- IPCData *ipc; // to store our NEW handle
-
- struct Screen *screen;
- } PassingData;
-
- /********************************************************************/
- // locale prototypes and variables
-
- ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
- register __a1 PassingData *pd );
-
- void __saveds New_Proc( void );
-
- BOOL OpenDOpusWin( WindowHandle *wh ); // the same old function
-
- BOOL HandleWindow( WindowHandle *wh ); // the same old function
-
-
- extern IPCData *proc_ipc;
- // declared in modinit.c, because must be initialized to NULL on startup
-
- /********************************************************************/
- // this is the same function like in DetachWindow.
- // it is the first special function we need...
-
- void OwnWindow( STRPTR args, struct Screen *screen )
- {
- PassingData *pd;
-
- if( (pd = AllocMemH(mempool, sizeof(PassingData))) ) // allocate some memory
- {
- pd->screen = screen; // store the screen pointer
-
- if( !proc_ipc ) // only if the process is not already running
- {
- // now some special stuff, but everything is needed here...
- pd->a4 = getreg( REG_A4 );
- pd->module = (struct Library *) getreg( REG_A6 );
- pd->library = DOpusBase;
-
- // now we are ready to call IPC_Launch()
- IPC_Launch( 0,
- &proc_ipc, // pointer to pointer to the IPC of the new process, for storing...
- "ExampleWindow", // name of the new process
- (ULONG) New_Proc, // entrypoint of the new process
- 4096, // stack to use
- (ULONG) pd, // data to pass to the new process
- DOSBase ); // pointer to dos.library
-
-
-
- if( !proc_ipc ) // if detaching failed...
- {
- FreeMemH( pd );
- return;
- }
-
- Delay( 10 ); // give a small time for startup...
- // not really needed
- }
-
- // now should our process running
- // since we use in the process not the arguments on startup to save
- // some work, we have to pass it now.
-
- IPC_Command( proc_ipc, // "address" (IPCData) of receiver
- NULL, // we use no commands here
- NULL, // also no flags
- args, // our data to pass to the new process
- NULL, // no other data (will be FreeVec'd)
- REPLY_NO_PORT ); // use normal DOpus IPC_Reply() later
-
- FreeMemH( pd );
- }
- // ready... :)
- }
-
- // let's do now the second special function
-
- ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
- register __a1 PassingData *pd )
- {
- // you may use this function also to setup things for your
- // main process, but you should not call any IPC functions here !
- // we do only the minimum required..., but you will get some small
- // warnings from your compiler. Just ignore them now - they does
- // not appear, if we would do here some more things...
-
- struct Library *DOpusBase;
-
- // fix A4
- putreg( REG_A4, pd->a4 );
-
- // store IPC pointer
- pd->ipc = ipc;
-
- // get dopus.library - one warning now
- DOpusBase = pd->library;
-
- // now may follow your initialization
-
- // if something fails and you must quit, you should do:
- // return FALSE;
-
- // increase our library counter, so we can not be flushed
- // do not forget to decrease it, if your detached process ends
- pd->module->lib_OpenCnt++;
-
- return TRUE; // all was successfully
- }
-
- void __saveds New_Proc( void )
- {
- // this is now just the same like until now our OwnWindow() function
-
- WindowHandle *wh;
- PassingData *pd;
- IPCData *ipc;
- IPCMessage *ipcmsg;
- struct Library *DOpusBase;
- struct Library *module;
-
- // but we must do some additional things
-
- // get dopus library
- if( !(DOpusBase = (struct Library *) FindName(&((struct ExecBase *)*((ULONG *)4))->LibList, "dopus5.library")) )
- return;
-
- // do startup
- ipc = IPC_ProcStartup( (ULONG *) &pd, New_Proc_Startup );
-
- // fix A4 so we can access global data in the module (eg library bases)
- putreg( REG_A4, pd->a4 );
-
- // we must store this pointer too
- module = pd->module;
-
- // something failed until now ?
- if( !ipc )
- {
- if( pd )
- {
- IPC_Free( pd->ipc ); // possible it has a value here
- FreeMemH( pd ); // free our memory
- }
-
- return;
- }
-
- if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
- {
- if( OpenDOpusWin(wh) ) // open the window
- {
- // before we have set on this place the value of our
- // textgadget, but now we have not the arguments. So
- // we wait to set the value until the command arrives.
-
- while( TRUE )
- {
- // I use here Wait(), so it is easier with the changes
-
- wh->signals = Wait( 1 << proc_ipc->command_port->mp_SigBit | // wait for IPC messages
- 1 << wh->win->UserPort->mp_SigBit ); // wait for window events
-
- if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
- if( HandleWindow(wh) )
- break; // does end the while loop
-
- if( wh->signals & 1 << proc_ipc->command_port->mp_SigBit ) // if we have got an IPC message
- {
- while( (ipcmsg = (IPCMessage *) GetMsg(proc_ipc->command_port)) )
- {
-
- // we copy now the arguments into the text gadget
- // if we have supplied some..., else it will be cleared
- // I do not cut here the last signs...
-
- SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) ipcmsg->data );
-
- IPC_Reply( ipcmsg ); // do not use ReplyMsg() or something else !
- }
- }
- }
-
- CloseConfigWindow( wh->win );
- }
-
- FreeMemH( wh ); // free our memory
- }
-
- // decrease our Library access counter, since we have increased it before
- --module->lib_OpenCnt;
-
- // since we are here a detached process, we must do some other cleanup too
- IPC_Free( proc_ipc );
-
- proc_ipc = NULL; // do not forget this...
- }
-
- /********************************************************************/
- // This function does open our window. We could have done this in the
- // function OwnWindow() too, but we need this function later again.
-
- BOOL OpenDOpusWin( WindowHandle *wh )
- {
- NewConfigWindow ncfgwin; // we need a NewConfigWindow structure too
- // of couse you could also allocate it with
- // AllocMemH()...
-
- // and have to fill it
-
- ncfgwin.nw_Parent = wh->screen; // open on this screen
-
- // getting a localized title...
- ncfgwin.nw_Title = DOpusGetString( locale, MSG_WINDOW_TITLE );
-
- ncfgwin.nw_Dims = &cfgwin; // a pointer to the ConfigWin structure
- ncfgwin.nw_Locale = locale; // the module locale pointer (from modinit.c)
- ncfgwin.nw_Port = NULL; // we doesn't supply a port
- ncfgwin.nw_Font = NULL; // just taking the screen font
- ncfgwin.nw_Flags = WINDOW_REQ_FILL | // fill with stripple pattern
- WINDOW_AUTO_KEYS | // handle keys automatic
- WINDOW_SCREEN_PARENT; // nw_Parent points to a screen
-
- if( (wh->win = OpenConfigWindow(&ncfgwin)) ) // open the window
- {
- if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
- return TRUE;
-
- CloseConfigWindow( wh->win ); // in error case do not forget :-)
- }
-
- return FALSE;
- }
-
-
- /********************************************************************/
- // we does only close the window, if the closegadget was pressed
- // if you want to close it within a gadget, you must only in the
- // right case set "stop" to TRUE
-
- BOOL HandleWindow( WindowHandle *wh )
- {
- BOOL stop = FALSE;
- ULONG value;
-
- while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
- {
- switch( wh->imsg->Class ) // let's handle the IDCMP
- {
- case IDCMP_GADGETUP:
- switch( GET_ID(wh->imsg) )
- {
- case GADGET_ID_CYCLE: // we copy simply the same text to the text gadget
-
- value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE ) + MSG_CLICK_ME;
- SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, value) );
- break;
-
- case GADGET_ID_OKAY: // doing a message
-
- SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
- break;
-
- case GADGET_ID_CANCEL:
- SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
- break;
- }
-
- break;
-
- case IDCMP_CLOSEWINDOW:
- // we can not simply return here, the IntuiMessage must replied first
-
- stop = TRUE;
- break;
- }
-
- ReplyWindowMsg( wh->imsg );
-
- // remember: You should not use any other routines
- // to get/reply the messages of this window than
- // GetWindowMsg() and ReplyWindowMsg() !!
- }
-
- return stop;
- }
-